<template>
  <div ref="MonacoEditorRef" class="wft-monaco-editor" :style="monacoEditorStyle" />
</template>
<script>
import * as monaco from 'monaco-editor'
import registryCompletion from './register'
registryCompletion(monaco)
const defaultOptions = {
  // 是否启用预览图
  minimap: { enabled: true },
  // 圆角
  roundedSelection: true,
  // 主题
  theme: 'vs',
  // 主键
  multiCursorModifier: 'ctrlCmd',
  // 滚动条
  scrollbar: {
    verticalScrollbarSize: 8,
    horizontalScrollbarSize: 8
  },
  // 行号
  lineNumbers: 'on',
  // tab大小
  tabSize: 2,
  //字体大小
  fontSize: 16,
  // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
  autoIndent: 'advanced',
  // 自动布局
  automaticLayout: false,
}
export default {
  data () {
    return {
      monacoEditor: null
    }
  },
  props: {
    width: {
      type: [Number, String],
      default: '100%'
    },
    height: {
      type: [Number, String],
      default: '100%'
    },
    value: {
      type: String,
      default: ''
    },
    options: {
      type: Object,
      default: () => ({})
    }
  },
  computed: {
    monacoEditorStyle() {
      return {
        width: typeof this.width === 'number' ? `${this.width}px` : this.width,
        height: typeof this.height === 'number' ? `${this.height}px` : this.height
      }
    }
  },
  watch: {
    value() {
      if(!this.monacoEditor) return
      this.updateVal()
    },
    options: {
      handler (val) {
        if(!this.monacoEditor) return
        this.monacoEditor.updateOptions({ ...val })
      },
      deep: true
    }
  },
  mounted () {
    this.initEditor()
  },
  methods: {
    // 初始化编辑器实例
    initEditor () {
      this.monacoEditor = monaco.editor.create(this.$refs.MonacoEditorRef, {
        value: this.value,
        ...defaultOptions,
        ...this.options
      })
      setTimeout(async () => {
        await this.formatDoc()
      }, 100)
      // 监听编辑器content变化
      this.monacoEditor.onDidChangeModelContent(() => {
        // vue2中 使用 $emit('input', this.monacoEditor.getValue()) 实现双向绑定  导致编辑器内的光标一直闪烁乱跑 原因未知 并且父组件不能直接在模板上获取值并赋值 必须要再定义一个变量来接受才行
        // 说白了 这个monacoEditor编辑器不支持数据双向绑定
        // this.$emit('input', this.monacoEditor.getValue())
        this.$emit('change', this.monacoEditor.getValue())
      })
    },
    // 更新编辑器内容
    updateVal() {
      this.$nextTick(() => {
        if(this.monacoEditor.getOption(monaco.editor.EditorOption.readOnly)) {
          this.monacoEditor.updateOptions({ readOnly: false })
        }
        this.monacoEditor.setValue(this.value)
        setTimeout(async () => {
          await this.formatDoc()
        }, 10)
      })
    },
    async formatDoc() {
      await this.monacoEditor.getAction('editor.action.formatDocument').run()
    }
  }
}

</script>
<style scoped>
.wft-monaco-editor {
  overflow: hidden;
}
</style>
